package com.tiny.mirror.service.product.common.config;

import com.tiny.mirror.service.product.common.config.bean.RedisConfigBean;
import com.tiny.mirror.service.product.common.config.bean.RedisConfigBean.FakeHostAndPort;
import java.util.Set;
import javax.annotation.Resource;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedisConfig {

  @Resource
  private RedisConfigBean redisConfigBean;

  @Bean(destroyMethod = "shutdown")
  public RedissonClient redisson() {
    Set<FakeHostAndPort> nodes = redisConfigBean.getHosts();
    if (nodes.size() > 1) {
      return masterAndSlave(nodes);
    } else {
      return single(nodes);
    }
  }

  public RedissonClient masterAndSlave(Set<FakeHostAndPort> nodes) {
    Config config = new Config();
    config.setMaxCleanUpDelay(300);
    config.setMinCleanUpDelay(5);
    ClusterServersConfig clusterServersConfig = config.useClusterServers();
    clusterServersConfig.setPingConnectionInterval(50000);
    clusterServersConfig.setTimeout(5000);
    clusterServersConfig.setTcpNoDelay(true);
    clusterServersConfig.setKeepAlive(true);
    clusterServersConfig.setMasterConnectionPoolSize(32);
    clusterServersConfig.setSlaveConnectionPoolSize(8);
    clusterServersConfig.setMasterConnectionMinimumIdleSize(5);
    clusterServersConfig.setSlaveConnectionMinimumIdleSize(3);
    nodes.forEach(fakeHostAndPort -> clusterServersConfig
        .addNodeAddress(
            "redis://" + fakeHostAndPort.getHost() + ":" + fakeHostAndPort.getPort()));
    return Redisson.create(config);
  }

  public RedissonClient single(Set<FakeHostAndPort> nodes) {
    Config config = new Config();
    config.setMaxCleanUpDelay(300);
    config.setMinCleanUpDelay(5);
    SingleServerConfig singleServerConfig = config.useSingleServer();
    singleServerConfig.setPingConnectionInterval(50000);
    singleServerConfig.setTimeout(5000);
    singleServerConfig.setTcpNoDelay(true);
    singleServerConfig.setKeepAlive(true);
    singleServerConfig.setConnectionPoolSize(32);
    singleServerConfig.setConnectionMinimumIdleSize(4);
    singleServerConfig.setPassword(redisConfigBean.getPassword());
    nodes.forEach(fakeHostAndPort -> singleServerConfig
        .setAddress("redis://" + fakeHostAndPort.getHost() + ":" + fakeHostAndPort.getPort()));
    return Redisson.create(config);
  }
}
